package order

import (
	"booking/common/handler"
	"booking/common/utils"
	"booking/common/validator"
	"booking/models"
	"encoding/json"
	"fmt"
	"time"

	"github.com/gin-gonic/gin"
	"gorm.io/gorm"
)

func Save(c *gin.Context) {
	var params struct {
		OrderNo          string               `json:"order_no"`
		Source           string               `json:"source" binding:"required"`
		CustomerName     string               `json:"customer_name" binding:"required"`
		SignerName       string               `json:"signer_name" binding:"required"`
		SignDate         string               `json:"sign_date" binding:"required"`
		PushDate         string               `json:"push_date"`
		PushTime         string               `json:"push_time"`
		CompleteDate     string               `json:"complete_date"`
		TaxpayerNo       string               `json:"taxpayer_no"`
		ProjectRecipient string               `json:"project_recipient" binding:"required"`
		LayoutPerson     string               `json:"layout_person" binding:"required"`
		Registrant       string               `json:"registrant"`
		RegistrationNo   string               `json:"registration_no"`
		LegalPersonName  string               `json:"legal_person_name"`
		LegalPersonPhone string               `json:"legal_person_phone"`
		LegalPersonIdno  string               `json:"legal_person_idno"`
		SettlementMethod string               `json:"settlement_method"`
		ConsigneeCity    string               `json:"consignee_city"`
		SignCompany      string               `json:"sign_company"`
		Attachments      []models.Attachments `json:"attachments"`
		RecipientName    string               `json:"recipient_name" binding:"required"`
		RecipientPhone   string               `json:"recipient_phone" binding:"required"`
		RecipientCity    string               `json:"recipient_city"`
		RecipientAddress string               `json:"recipient_address" binding:"required"`
		Couriers         []struct {
			RecipientName    string               `json:"recipient_name"`
			RecipientPhone   string               `json:"recipient_phone"`
			RecipientCity    string               `json:"recipient_city"`
			RecipientAddress string               `json:"recipient_address"`
			Courier          string               `json:"courier"`
			TrackingNo       string               `json:"tracking_no"`
			ShipTime         string               `json:"ship_time"`
			DeliveryTime     string               `json:"delivery_time"`
			Attachments      []models.Attachments `json:"attachments"`
		} `json:"couriers"`
		Products []struct {
			ProductDesc    string  `json:"product_desc"`
			Quantity       int     `json:"quantity"`
			UnitPrice      float64 `json:"unit_price"`
			Amount         float64 `json:"amount"`
			ReceivedAmount float64 `json:"received_amount"`
			Remark         string  `json:"remark"`
		} `json:"products"`
	}

	if err := c.ShouldBindJSON(&params); err != nil {
		handler.Error(validator.Translate(err), c)
		return
	}

	// 解析日期字段
	signDate, err := parseDate(params.SignDate)
	if params.SignDate != "" && err != nil {
		handler.Error("签单日期格式错误，请使用 YYYY-MM-DD 格式", c)
		return
	}

	pushDate, err := parseDate(params.PushDate)
	if params.PushDate != "" && err != nil {
		handler.Error("推送时间格式错误，请使用 YYYY-MM-DD 格式", c)
		return
	}

	// 完成时间处理 - 空字符串时存储为 null
	var completeDate *time.Time
	if params.CompleteDate != "" {
		parsedDate, err := parseDate(params.CompleteDate)
		if err != nil {
			handler.Error("完成时间格式错误，请使用 YYYY-MM-DD 格式", c)
			return
		}
		completeDate = parsedDate
	}

	// 序列化附件
	attachmentsJSON, err := json.Marshal(params.Attachments)
	if err != nil {
		handler.Error("附件序列化失败", c)
		return
	}

	// 获取数据库连接
	db := models.Db

	// 开始事务
	tx := db.Begin()
	defer func() {
		if r := recover(); r != nil {
			tx.Rollback()
		}
	}()

	// 判断是新增还是修改
	isUpdate := params.OrderNo != ""
	var order models.Order

	if isUpdate {
		// 修改订单
		if err := tx.Where("order_no = ?", params.OrderNo).First(&order).Error; err != nil {
			tx.Rollback()
			handler.Error("订单不存在", c)
			return
		}
	} else {
		// 新增订单，生成订单号
		order.OrderNo = models.GenerateOrderNo()
		order.AdminId = 1 // 默认管理员ID，实际应从登录信息中获取
	}

	// 设置订单基本信息
	order.Source = params.Source
	order.CustomerName = params.CustomerName
	order.SignerName = params.SignerName
	order.SignDate = signDate
	order.PushDate = pushDate
	order.PushTime = params.PushTime
	if completeDate != nil {
		order.CompleteDate = completeDate
	} else {
		// 设置为nil，GORM会将其转换为null存储
		order.CompleteDate = nil
	}
	order.TaxpayerNo = params.TaxpayerNo
	order.ProjectRecipient = params.ProjectRecipient
	order.LayoutPerson = params.LayoutPerson
	order.Registrant = params.Registrant
	order.RegistrationNo = params.RegistrationNo
	order.LegalPersonName = params.LegalPersonName
	order.LegalPersonPhone = params.LegalPersonPhone
	order.LegalPersonIdno = params.LegalPersonIdno
	order.SettlementMethod = params.SettlementMethod
	order.ConsigneeCity = params.ConsigneeCity
	order.SignCompany = params.SignCompany
	order.Status = models.OrderStatusProducing
	order.Attachments = string(attachmentsJSON)
	order.RecipientName = params.RecipientName
	order.RecipientPhone = params.RecipientPhone
	order.RecipientCity = params.RecipientCity
	order.RecipientAddress = params.RecipientAddress
	order.UpdatedTime = time.Now()

	// 保存订单
	if isUpdate {
		if err := tx.Save(&order).Error; err != nil {
			tx.Rollback()
			handler.Error("更新订单失败: "+err.Error(), c)
			return
		}
	} else {
		order.CreatedTime = time.Now()
		if err := tx.Create(&order).Error; err != nil {
			tx.Rollback()
			handler.Error("创建订单失败: "+err.Error(), c)
			return
		}
	}

	// 处理物流信息
	if err := handleCouriers(tx, order.OrderNo, params.Couriers); err != nil {
		tx.Rollback()
		handler.Error("处理物流信息失败: "+err.Error(), c)
		return
	}
	var totalAmount float64 = 0
	// 处理产品信息
	if totalAmount, err = handleProducts(tx, order.OrderNo, params.Products); err != nil {
		tx.Rollback()
		handler.Error("处理产品信息失败: "+err.Error(), c)
		return
	}
	tx.Model(models.Order{}).Where(map[string]any{
		"order_no": order.OrderNo,
	}).Update("total_amount", totalAmount)

	// 提交事务
	if err := tx.Commit().Error; err != nil {
		handler.Error("保存失败: "+err.Error(), c)
		return
	}

	// 返回成功消息
	result := gin.H{
		"message":  "订单创建成功",
		"order_no": order.OrderNo,
	}
	if isUpdate {
		result["message"] = "订单更新成功"
	}
	handler.Success(result, c)
}

// parseDate 解析日期字符串为 *time.Time
func parseDate(dateStr string) (*time.Time, error) {
	t, err := time.Parse("2006-01-02", dateStr)
	if err != nil {
		return nil, err
	}
	return &t, nil
}

// handleCouriers 处理物流信息
func handleCouriers(tx *gorm.DB, orderNo string, couriers []struct {
	RecipientName    string               `json:"recipient_name"`
	RecipientPhone   string               `json:"recipient_phone"`
	RecipientCity    string               `json:"recipient_city"`
	RecipientAddress string               `json:"recipient_address"`
	Courier          string               `json:"courier"`
	TrackingNo       string               `json:"tracking_no"`
	ShipTime         string               `json:"ship_time"`
	DeliveryTime     string               `json:"delivery_time"`
	Attachments      []models.Attachments `json:"attachments"`
}) error {
	// 删除原有物流信息
	if err := tx.Where("order_no = ?", orderNo).Delete(&models.OrderCourier{}).Error; err != nil {
		return err
	}

	// 添加新的物流信息
	for _, c := range couriers {
		// 使用指针类型处理空日期，确保存储为null
		var shipTime *time.Time
		var deliveryTime *time.Time
		var err error

		if c.ShipTime != "" {
			parsedTime, err := parseDate(c.ShipTime)
			if err != nil {
				return fmt.Errorf("发货时间格式错误: %s", c.ShipTime)
			}
			shipTime = parsedTime
		}

		if c.DeliveryTime != "" {
			parsedTime, err := parseDate(c.DeliveryTime)
			if err != nil {
				return fmt.Errorf("送达时间格式错误: %s", c.DeliveryTime)
			}
			deliveryTime = parsedTime
		}

		// 序列化物流附件
		attachmentsJSON, err := json.Marshal(c.Attachments)
		if err != nil {
			return err
		}

		// 确定物流状态
		courierStatus := models.CourierStatusPending
		if shipTime != nil && deliveryTime == nil {
			courierStatus = models.CourierStatusShipped
		} else if deliveryTime != nil {
			courierStatus = models.CourierStatusDelivered
		}

		// 构造物流记录
		courier := models.OrderCourier{
			OrderNo:          orderNo,
			RecipientName:    c.RecipientName,
			RecipientPhone:   c.RecipientPhone,
			RecipientCity:    c.RecipientCity,
			RecipientAddress: c.RecipientAddress,
			Courier:          c.Courier,
			TrackingNo:       c.TrackingNo,
			ShipTime:         shipTime,
			DeliveryTime:     deliveryTime,
			Attachments:      string(attachmentsJSON),
			CourierStatus:    courierStatus,
		}

		if err := tx.Create(&courier).Error; err != nil {
			return err
		}
	}

	return nil
}

// handleProducts 处理产品信息
func handleProducts(tx *gorm.DB, orderNo string, products []struct {
	ProductDesc    string  `json:"product_desc"`
	Quantity       int     `json:"quantity"`
	UnitPrice      float64 `json:"unit_price"`
	Amount         float64 `json:"amount"`
	ReceivedAmount float64 `json:"received_amount"`
	Remark         string  `json:"remark"`
}) (float64, error) {
	// 删除原有产品信息
	if err := tx.Where("order_no = ?", orderNo).Delete(&models.OrderProduct{}).Error; err != nil {
		return 0, err
	}
	var totalAmount float64 = 0
	// 添加新产品信息
	for _, p := range products {
		product := models.OrderProduct{
			OrderNo:        orderNo,
			ProductDesc:    p.ProductDesc,
			Quantity:       p.Quantity,
			UnitPrice:      p.UnitPrice,
			Amount:         p.Amount,
			ReceivedAmount: p.ReceivedAmount,
			Remark:         p.Remark,
		}

		if err := tx.Create(&product).Error; err != nil {
			return 0, err
		}
		totalAmount = utils.NewBatchMath(2).Add(totalAmount).Add(product.Amount).Float64()
	}

	return totalAmount, nil
}
